﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using AutoMapper;
using MyBlog.DataEntity;
using MyBlog.Model;

namespace MyBlog.Common
{
    public static class AutoMapperConfig
    {
        /// <summary>
        /// 配置实体映射
        /// </summary>
        public static void Configure()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<AccountModel, Tbl_Account>();
                cfg.CreateMap<AlbumDetailModel, Tbl_AlbumDetail>();
                cfg.CreateMap<AlbumModel, Tbl_Album>();
                cfg.CreateMap<ArticleCommentModel, Tbl_ArticleComment>();
                cfg.CreateMap<ArticleModel, Tbl_Article>().ForMember(x => x.Tbl_Category, y => y.MapFrom(x => x.CategoryModels))
                .ForMember(x => x.Tbl_Tag, y => y.MapFrom(x => x.TagModels));
                cfg.CreateMap<CategoryModel, Tbl_Category>().ForMember(x => x.Tbl_Article, y => y.MapFrom(x => x.ArticleModels));
                cfg.CreateMap<HeaderModel, Tbl_Header>();
                cfg.CreateMap<MessageModel, Tbl_Message>();
                cfg.CreateMap<MoodCommentModel, Tbl_MoodComment>();
                cfg.CreateMap<MoodModel, Tbl_Mood>();
                cfg.CreateMap<MsgReplyModel, Tbl_MsgReply>();
                cfg.CreateMap<PicCommentModel, Tbl_PicComment>();
                cfg.CreateMap<SysLogModel, Tbl_SysLog>();
                cfg.CreateMap<VisitorModel, Tbl_Visitor>();
                cfg.CreateMap<BugModel, Tbl_Bug>();
                cfg.CreateMap<TagModel, Tbl_Tag>();
                cfg.CreateMap<ConcernModel, Tbl_Concerns>();
                cfg.CreateMap<NoticeModel, Tbl_Notice>().ForMember(x => x.NoticeType, y => y.MapFrom(x => (int)x.NoticeEnum));
                cfg.CreateMap<SysHistoryModel, Tbl_SysHistory>();
                cfg.CreateMap<WordsModel, Tbl_Words>();
                cfg.CreateMap<WordCommentModel, Tbl_WordComment>();
                cfg.CreateMap<SysInfoModel, Tbl_SysInfo>();

                cfg.CreateMap<Tbl_Category, CategoryModel>()
                .ForMember(x => x.Account, y => y.MapFrom(x => x.Tbl_Account))
                .ForMember(x => x.ArticleModels, y => y.MapFrom(x => x.Tbl_Article));

                cfg.CreateMap<Tbl_Header, HeaderModel>();

                cfg.CreateMap<Tbl_Account, AccountModel>()
                    .ForMember(x => x.AlbumModels, y => y.MapFrom(x => x.Tbl_Album))
                    .ForMember(x => x.ArticleModels, y => y.MapFrom(x => x.Tbl_Article))
                    .ForMember(x => x.Header, y => y.MapFrom(x => x.Tbl_Header))
                    .ForMember(x => x.MoodModels, y => y.MapFrom(x => x.Tbl_Mood))
                    .ForMember(x => x.CategoryModels, y => y.MapFrom(x => x.Tbl_Category))
                    .ForMember(x => x.MessageModels, y => y.MapFrom(x => x.Tbl_Message))
                    .ForMember(x => x.PersonalProfile, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.PersonalProfile)))
                    .ForMember(x => x.WantSay, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.WantSay)))
                    .ForMember(x => x.Motto, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.Motto)))
                    .ForMember(x => x.TagModels, y => y.MapFrom(x => x.Tbl_Tag))
                    .ForMember(x => x.MyConcernUsers, y => y.MapFrom(x => x.MyConcernUsers))
                    .ForMember(x => x.ConcernMeUsers, y => y.MapFrom(x => x.ConcernMeUsers))
                    .ForMember(x => x.MyNotices, y => y.MapFrom(x => x.MyNotices));

                cfg.CreateMap<Tbl_Album, AlbumModel>()
                    .ForMember(x => x.Account, y => y.MapFrom(x => x.Tbl_Account))
                    .ForMember(x => x.AlbumDetails, y => y.MapFrom(x => x.Tbl_AlbumDetail));

                cfg.CreateMap<Tbl_AlbumDetail, AlbumDetailModel>()
                    .ForMember(x => x.Album, y => y.MapFrom(x => x.Tbl_Album))
                    .ForMember(x => x.PicCommentModels, y => y.MapFrom(x => x.Tbl_PicComment));

                cfg.CreateMap<Tbl_Article, ArticleModel>()
                    .ForMember(x => x.Content, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.Content)))
                    .ForMember(x => x.Title, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.Title)))
                    .ForMember(x => x.Profile, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.Profile)))
                    .ForMember(x => x.Account, y => y.MapFrom(x => x.Tbl_Account))
                    .ForMember(x => x.ArticleCommentModels, y => y.MapFrom(x => x.Tbl_ArticleComment))
                    .ForMember(x => x.CategoryModels, y => y.MapFrom(x => x.Tbl_Category))
                    .ForMember(x => x.TagModels, y => y.MapFrom(x => x.Tbl_Tag));

                cfg.CreateMap<Tbl_ArticleComment, ArticleCommentModel>()
                    .ForMember(x => x.ArticleCommentModels, y => y.MapFrom(x => x.ArticleComments))
                    .ForMember(x => x.Parent, y => y.MapFrom(x => x.Parent))
                    .ForMember(x => x.Content, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.Content)))
                    .ForMember(x => x.Article, y => y.MapFrom(x => x.Tbl_Article));

                cfg.CreateMap<Tbl_PicComment, PicCommentModel>()
                    .ForMember(x => x.Content, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.Content)))
                    .ForMember(x => x.AlbumDetail, y => y.MapFrom(x => x.Tbl_AlbumDetail))
                    .ForMember(x => x.PicComments, y => y.MapFrom(x => x.PicComments));

                cfg.CreateMap<Tbl_Mood, MoodModel>()
                    .ForMember(x => x.Account, y => y.MapFrom(x => x.Tbl_Account))
                    .ForMember(x => x.MoodCommentModels, y => y.MapFrom(x => x.Tbl_MoodComment))
                    .ForMember(x => x.Content, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.Content)));

                cfg.CreateMap<Tbl_MoodComment, MoodCommentModel>()
                    .ForMember(x => x.Mood, y => y.MapFrom(x => x.Tbl_Mood));

                cfg.CreateMap<Tbl_Words, WordsModel>()
                   .ForMember(x => x.Account, y => y.MapFrom(x => x.Tbl_Account))
                   .ForMember(x => x.WordComments, y => y.MapFrom(x => x.Tbl_WordComment))
                   .ForMember(x => x.Content, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.Content)));

                cfg.CreateMap<Tbl_WordComment, WordCommentModel>()
                    .ForMember(x => x.Words, y => y.MapFrom(x => x.Tbl_Words));

                cfg.CreateMap<Tbl_Message, MessageModel>()
                    .ForMember(x => x.Content, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.Content)))
                    .ForMember(x => x.Account, y => y.MapFrom(x => x.Tbl_Account))
                    .ForMember(x => x.MsgReplyModels, y => y.MapFrom(x => x.Tbl_MsgReply));

                cfg.CreateMap<Tbl_MsgReply, MsgReplyModel>()
                    .ForMember(x => x.Content, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.Content)))
                    .ForMember(x => x.Message, y => y.MapFrom(x => x.Tbl_Message))
                    //.ForMember(x => x.Parent, y => y.MapFrom(x => x.Parent))
                    .ForMember(x => x.MsgReplyModels, y => y.MapFrom(x => x.MsgReplyList));

                cfg.CreateMap<Tbl_Bug, BugModel>()
                    .ForMember(x => x.BugDetail, y => y.MapFrom(x => HttpUtility.HtmlDecode(x.BugDetail)))
                    //.ForMember(x => x.Parent, y => y.MapFrom(x => x.Parent))
                    .ForMember(x => x.BugList, y => y.MapFrom(x => x.BugList));

                cfg.CreateMap<Tbl_Tag, TagModel>()
                    .ForMember(x => x.Account, y => y.MapFrom(x => x.Tbl_Account))
                    .ForMember(x => x.ArticleModels, y => y.MapFrom(x => x.Tbl_Article));

                cfg.CreateMap<Tbl_Concerns, ConcernModel>()
                   .ForMember(x => x.Account, y => y.MapFrom(x => x.Account))
                   .ForMember(x => x.ConcernUser, y => y.MapFrom(x => x.ConcernUser));

                cfg.CreateMap<Tbl_Notice, NoticeModel>().ForMember(x => x.NoticeEnum, y => y.MapFrom(x => x.NoticeType));

                cfg.CreateMap<Tbl_SysHistory, SysHistoryModel>();

                cfg.CreateMap<Tbl_SysInfo, SysInfoModel>();
            });

            //Mapper.AssertConfigurationIsValid();
        }

        /// <summary>
        /// 利用AutoMapper转换对象
        /// </summary>
        /// <typeparam name="TSource">源类型</typeparam>
        /// <typeparam name="TTarget">目标类型</typeparam>
        /// <param name="obj">包含源实体数据的对象</param>
        /// <param name="isMap">实体映射是否已配置，默认为true</param>
        /// <returns></returns>
        public static TTarget Cast<TSource, TTarget>(this TSource obj, bool isMap = true)
            where TSource : class
            where TTarget : class
        {
            if (null == obj) { return default(TTarget); }
            if (!isMap) { Mapper.CreateMap<TSource, TTarget>(); }
            var result = Mapper.Map<TSource, TTarget>(obj);
            return result;
        }

        /// <summary>
        /// 快速利用AutoMapper转换对象
        /// </summary>
        /// <typeparam name="T">目标类型</typeparam>
        /// <param name="obj">包含源实体数据的对象</param>
        /// <returns></returns>
        public static TTarget Map<TSource, TTarget>(this TSource obj)
            where TSource : class
            where TTarget : class
        {
            if (null == obj) return default(TTarget);
            Mapper.CreateMap<TSource, TTarget>();
            var result = Mapper.Map<TTarget>(obj);
            return result;
        }

        /// <summary>
        /// 集合列表类型映射，源类型未确定
        /// </summary>
        /// <typeparam name="TTarget"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static IEnumerable<TTarget> MapToList<TTarget>(this IEnumerable<object> source) where TTarget : class
        {
            if (null == source) { return default(List<TTarget>); }
            foreach (var item in source)
            {
                var type = item.GetType();
                Mapper.CreateMap(type, typeof(TTarget));
                break;
            }
            var result = Mapper.Map<List<TTarget>>(source);
            return result;
        }

        /// <summary>
        /// 集合列表类型映射，源类型已确定
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TTarget"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static List<TTarget> MapToList<TSource, TTarget>(this IEnumerable<TSource> source)
            where TSource : class
            where TTarget : class
        {
            if (null == source) { return default(List<TTarget>); }
            Mapper.CreateMap<TSource, TTarget>();
            return Mapper.Map<List<TTarget>>(source);
        }

    }
}
